/**
 *
 */
package de.cbf.cam.dsa.facet.weapon_cc.helper;

import java.beans.PropertyChangeSupport;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;

import de.cbf.util.uuidheader.entities.UUIDHeader;
import de.cbf.util.uuidheader.exceptions.EntityMergeException;

/**
 * @author Nebelritter
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
public class WeaponCC_CombatValues extends UUIDHeader {

	//property events name
	public static final String PN_TP				= "facet.weapon_cc.tp";
	public static final String PN_TP_KK_BASE		= "facet.weapon_cc.tp_kk_base";
	public static final String PN_TP_KK_STEP		= "facet.weapon_cc.tp_kk-step";

	public static final String PN_INI				= "facet.weapon_cc.ini";
	public static final String PN_WM_AT				= "facet.weapon_cc.wm_at";
	public static final String PN_WM_PA				= "facet.weapon_cc.wm_at";
	public static final String PN_DK_BITS			= "facet.weapon_cc.dk_bits";
	public static final String PN_SPECIAL_BITS 		= "facet.weapon_cc.special_bits";

	///property events index
	public static final int PI_TP				= 10;
	public static final int PI_TP_KK_BASE		= 11;
	public static final int PI_TP_KK_STEP		= 12;
	public static final int PI_INI				= 13;
	public static final int PI_WM_AT			= 14;
	public static final int PI_WM_PA			= 15;
	public static final int PI_DK_BITS			= 16;
	public static final int PI_SPECIAL_BITS		= 17;

	//distance class distance constants
	public static final float DISTANCE_P 	= 3;
	public static final float DISTANCE_S 	= 2;
	public static final float DISTANCE_N	= 1;
	public static final float DISTANCE_H 	= 0.5f;

	//distance class bits
	public static final int DK_H =1<<1;
	public static final int DK_N =1<<2;
	public static final int DK_S =1<<3;
	public static final int DK_P =1<<4;

	//special bits
	public static final int SPECIAL_TWO_HANDED	=1<<1;
	public static final int SPECIAL_PRIVILIGED	=1<<2;
	public static final int SPECIAL_IMPROVISED	=1<<3;
	
	public static final String	UNSET_TP 			= "";
	public static final Integer	UNSET_TP_KK_BASE 	= -1;
	public static final Integer	UNSET_TP_KK_STEP 	= -1;
	public static final Integer	UNSET_INI 			= Integer.MIN_VALUE;
	public static final Integer	UNSET_WM_AT 		= Integer.MIN_VALUE;
	public static final Integer	UNSET_WM_PA 		= Integer.MIN_VALUE;	
	public static final Integer	UNSET_DK_BITS 		= -1;
	public static final Integer	UNSET_SPECIAL_BITS 	= -1;
	
	public static final String	TEXT_UNSET_TP 			= "TP not set";	
	public static final String	TEXT_UNSET_TP_KK_BASE 	= "TP_KK_BASE not set";	
	public static final String	TEXT_UNSET_TP_KK_STEP	= "TP_KK_STEP not set";	
	public static final String	TEXT_UNSET_INI 			= "INI not set";	
	public static final String	TEXT_UNSET_WM_AT 		= "WM_AT not set";	
	public static final String	TEXT_UNSET_WM_PA 		= "WM_PA not set";	
	public static final String	TEXT_UNSET_DK_BITS 		= "DK_BITS not set";	
	public static final String	TEXT_UNSET_SPECIAL_BITS	= "SPECIAL_BITS not set";
	public static final String 	TEXT_UNSET_TALENTS		= "TALENTS not set";
	
	//Fields
	protected String 		fTP;//TODO should be DiceThrowDescription 
	protected Integer 		fTpKK_Base;
	protected Integer 		fTpKK_Step;

	protected Integer 		fIni;
	protected Integer 		fWmAT;
	protected Integer 		fWmPA;
	protected Integer 		fDkBits;
	protected Integer 		fSpecialBits;

	@XmlTransient
	protected PropertyChangeSupport propertyChangeSupport;

	public WeaponCC_CombatValues() {
		super();
	}

	/* (non-Javadoc)
	 * @see de.cbf.util.uuidheader.entities.NamedEntity#init()
	 */
	protected void init() {
		super.init();
		propertyChangeSupport = new PropertyChangeSupport(this);
		
		fTP				= UNSET_TP;
		fTpKK_Base		= UNSET_TP_KK_BASE;
		fTpKK_Step		= UNSET_TP_KK_STEP;
		fIni			= UNSET_INI;
		fWmAT			= UNSET_WM_AT;
		fWmPA 			= UNSET_WM_PA;
		fDkBits 		= UNSET_DK_BITS;
		fSpecialBits	= UNSET_SPECIAL_BITS;
	}

	protected void doMergeDataFrom(UUIDHeader entity, boolean i_am_older)
			throws EntityMergeException {
		if (entity instanceof WeaponCC_CombatValues) {
			WeaponCC_CombatValues other = (WeaponCC_CombatValues) entity;
			if(i_am_older){
				this.fTP = other.fTP;
				this.fTpKK_Base = other.fTpKK_Base;
				this.fTpKK_Step = other.fTpKK_Step;
				this.fIni = other.fIni;
				this.fWmAT = other.fWmAT;
				this.fWmPA = other.fWmPA;
				this.fDkBits = other.fDkBits;
				this.fSpecialBits = other.fSpecialBits;
			}
		}else{
			String mergeEntityClass = entity == null? "null":entity.getClass().getName();
			String errorMsg ="EntityToMerge "+mergeEntityClass+" does not fit class:"+this.getClass().getName();
			throw new EntityMergeException(errorMsg);
		}
	}

	public PropertyChangeSupport getPropertyChangeSupport() {
		return propertyChangeSupport;
	}
	
	public String getLogDescription() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("\t\t\t\t");
		//Tp		
		buffer.append(fTP);
		buffer.append("\t\t");
		//TP/KK			
		buffer.append(fTpKK_Base+"/"+fTpKK_Step);
		buffer.append("\t");
		//ini		
		buffer.append(fIni);
		buffer.append("\t");
		//Wm		
		buffer.append(fWmAT+"/"+fWmPA);
		buffer.append("\t");
		//dk		
		buffer.append(getDkLogDescription(fDkBits));
		buffer.append("\t\t");
		//specials		
		buffer.append(getSpecialsLogDescription(fSpecialBits));		
		
		buffer.append("\n");
		return buffer.toString();
	}

	protected String getDkLogDescription(Integer fDkBits) {
		String result ="";
		if((fDkBits|DK_H) != 0){
			result+="H";
		}
		if((fDkBits|DK_N) != 0){
			result+="N";
		}
		if((fDkBits|DK_S) != 0){
			result+="S";
		}
		if((fDkBits|DK_P) != 0){
			result+="P";
		}
		return result;
	}
	
	protected String getSpecialsLogDescription(Integer fSpecialBits) {
		String result ="";
		if((fSpecialBits|SPECIAL_PRIVILIGED) != 0){
			result+="p";
		}
		if((fSpecialBits|SPECIAL_TWO_HANDED) != 0){
			result+="z";
		}
		if((fSpecialBits|SPECIAL_IMPROVISED) != 0){
			result+="i";
		}		
		return result;
	}

	public String getTp() {
		return fTP;
	}

	public void setTp(String newTP) throws IllegalArgumentException {
		if(fTP != null && fTP.equals(newTP)){
            return;
        }
        String oldTP = fTP;
        fTP = newTP;
        propertyChangeSupport.fireIndexedPropertyChange(PN_TP, PI_TP, oldTP, fTP);
	}

	public Integer getTpKK_Base() {
		return fTpKK_Base;
	}

	public void setTpKK_Base(Integer newTpKK_Base) throws IllegalArgumentException{
		Integer oldTpKK_Base = this.fTpKK_Base;
		fTpKK_Base = newTpKK_Base;
		propertyChangeSupport.fireIndexedPropertyChange(PN_TP_KK_BASE, PI_TP_KK_BASE,
				oldTpKK_Base,fTpKK_Base);
	}

	public Integer getTpKK_Step() {
		return fTpKK_Step;
	}

	public void setTpKK_Step(Integer newTpKK_Step) throws IllegalArgumentException{
		Integer oldTpKK_Step = this.fTpKK_Step;
		fTpKK_Step = newTpKK_Step;
		propertyChangeSupport.fireIndexedPropertyChange(PN_TP_KK_STEP, PI_TP_KK_STEP,
				oldTpKK_Step,fTpKK_Step);
	}



	public Integer getIni() {
		return fIni;
	}

	public void setIni(Integer newIni) throws IllegalArgumentException{
		Integer oldIni = this.fIni;
		fIni = newIni;
		propertyChangeSupport.fireIndexedPropertyChange(PN_INI, PI_INI,
				oldIni,fIni);
	}

	public Integer getWmAT() {
		return fWmAT;
	}

	public void setWmAT(Integer newWmAT) throws IllegalArgumentException{
		Integer oldWmAT = this.fWmAT;
		fWmAT = newWmAT;
		propertyChangeSupport.fireIndexedPropertyChange(PN_WM_AT, PI_WM_AT,
				oldWmAT,fWmAT);
	}

	public Integer getWmPA() {
		return fWmPA;
	}

	public void setWmPA(Integer newWmPA) throws IllegalArgumentException{
		Integer oldWmPA = this.fWmPA;
		fWmPA = newWmPA;
		propertyChangeSupport.fireIndexedPropertyChange(PN_WM_PA, PI_WM_PA,
				oldWmPA,fWmPA);
	}

	public Integer getDkBits() {
		return fDkBits;
	}

	public void setDkBits(Integer newDkBits) throws IllegalArgumentException{
		Integer oldDkBits = this.fDkBits;
		fDkBits = newDkBits;
		propertyChangeSupport.fireIndexedPropertyChange(PN_DK_BITS, PI_DK_BITS,
				oldDkBits,fDkBits);
	}

	public Integer getSpecialBits() {
		return fSpecialBits;
	}

	public void setSpecialBits(Integer newSpecialBits) throws IllegalArgumentException{
		if(fSpecialBits != null && fSpecialBits.equals(newSpecialBits)){
            return;
        }
        Integer oldSpecialBits = fSpecialBits;
        fSpecialBits = newSpecialBits;
        propertyChangeSupport.fireIndexedPropertyChange(PN_SPECIAL_BITS, PI_SPECIAL_BITS, oldSpecialBits, fSpecialBits);
	}

	public String hasUnsetValues() {
		StringBuffer result = new StringBuffer();
		if(UNSET_TP.equals(fTP)){
			result.append(TEXT_UNSET_TP+"\n");
		}
		if(UNSET_TP_KK_BASE.equals(fTpKK_Base)){
			result.append(TEXT_UNSET_TP_KK_BASE+"\n");
		}
		if(UNSET_TP_KK_STEP.equals(fTpKK_Step)){
			result.append(TEXT_UNSET_TP_KK_STEP+"\n");
		}
		if(UNSET_INI.equals(fIni)){
			result.append(TEXT_UNSET_INI+"\n");
		}
		if(UNSET_WM_AT.equals(fWmAT)){
			result.append(TEXT_UNSET_WM_AT+"\n");
		}
		if(UNSET_WM_PA.equals(fWmPA)){
			result.append(TEXT_UNSET_WM_PA+"\n");
		}
		if(UNSET_DK_BITS.equals(fDkBits)){
			result.append(TEXT_UNSET_DK_BITS+"\n");
		}
		if(UNSET_SPECIAL_BITS.equals(fSpecialBits)){
			result.append(TEXT_UNSET_SPECIAL_BITS+"\n");
		}
		return result.toString();
	}



}
